package com.github.m6d21.sso.support.token;

import com.github.m6d21.sso.support.model.SsoTokenWrapper;
import com.github.m6d21.sso.common.util.BuildSignatureUtil;
import com.github.m6d21.sso.support.cache.Cache;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

/**
 *<p>
 *
 *</p>
 *
 * @author liuyang
 * @date 2018/12/10 Mon 14:07:00
 * @since 1.0.0
 */
@Component
public class SsoTokenHelper {

    private static final Logger LOG = LoggerFactory.getLogger(SsoTokenHelper.class);

    private static SsoTokenHelper helper = null;

    @Value("${sso.token.expire}")
    private int tokenExpire = 600;

    private SsoTokenHelper() {
    }

    @Resource(name = "redisCache")
    private Cache cache;

    @SuppressWarnings("all")
    @PostConstruct
    private void init() {
        helper = this;
        helper.cache = this.cache;
        helper.tokenExpire = this.tokenExpire;
    }

    public static SsoTokenWrapper createToken() {
        SsoTokenWrapper ssoTokenWrapper = new SsoTokenWrapper();
        ssoTokenWrapper.setToken(BuildSignatureUtil.createSignature());
        return ssoTokenWrapper;
    }

    /**
     * 保存至缓存
     * @param ssoTokenWrapper token包装类
     */
    public static void commit(SsoTokenWrapper ssoTokenWrapper) {
        if (ssoTokenWrapper != null && StringUtils.isNotBlank(ssoTokenWrapper.getToken())) {
            helper.cache.set(ssoTokenWrapper.getToken(), ssoTokenWrapper, helper.tokenExpire,
                TimeUnit.SECONDS);
        }
    }

    /**
     * 校验token
     *
     * @param token token字符串
     */
    public static SsoTokenWrapper verifyToken(String token) {
        SsoTokenWrapper ssoTokenWrapper = null;
        if (BuildSignatureUtil.verifySignature(token)) {
            try {
                //访问一次，对其有效期进行延长
                ssoTokenWrapper = getAndProlong(token);
            } catch (Exception e) {
                LOG.error("verifyToken(), 获取缓存对象失败：{}", e);
            }
        }
        return ssoTokenWrapper;
    }

    public static boolean clearToken(String token) {
        Boolean success = helper.cache.delete(token);
        return Optional.ofNullable(success).orElse(false);
    }


    private static SsoTokenWrapper getFromCache(String key) {
        return helper.cache.get(key, SsoTokenWrapper.class);
    }

    /**
     * 延长token过期时长
     *
     * @param token token字符串
     */
    private static SsoTokenWrapper getAndProlong(String token) {
        SsoTokenWrapper old = getFromCache(token);
        if (old != null) {
            old.setUpdateTime(System.currentTimeMillis());
            helper.cache.set(token, old, helper.tokenExpire, TimeUnit.SECONDS);
        }

        return old;
    }

}
